import { RouteRecordRaw } from "vue-router"
import { constantRoutes } from "@/router"
import { store, useUserStore } from "@/store"
import MenuAPI, { RouteVO } from "@/api/menu"

import { buildTree } from "@/utils"

const modules = import.meta.glob("../../views/**/**.vue")
const Layout = () => import("@/layout/index.vue")

export const usePermissionStore = defineStore("permission", () => {
  /**
   * 应用中所有的路由列表，包括静态路由和动态路由
   */
  const routes = ref<RouteRecordRaw[]>([])
  /**
   * 混合模式左侧菜单列表
   */
  const mixLeftMenus = ref<RouteRecordRaw[]>([])

  /**
   * 生成动态路由
   */
  function generateRoutes() {
    return new Promise<RouteRecordRaw[]>((resolve, reject) => {
      MenuAPI.getRoutes(useUserStore().user.username)
        .then((res: any) => {
          const convertRouteData: Array<RouteVO> = []
          if (res.data && res.data.length) {
            res.data.forEach((item: any) => {
              if (!item.pid || item.pid === 0) {
                item.component = "Layout"
                item.alwaysShow = false
                item.name = "/" + (item.name || item.path)
                item.path = "/" + item.path
              }
              convertRouteData.push({
                id: item.menu_id,
                pid: item.pid,
                meta: {
                  alwaysShow: item.alwaysShow,
                  icon: item.icon,
                  title: item.title,
                  hidden: Boolean(item.hidden),
                  roles: item.roles,
                  perms: item.permission,
                  keepAlive: true,
                },
                name: item.name,
                path: item.path,
                component: item.component,

                children: [],
              })
            })
          }
          const treeData = buildTree(convertRouteData, "id", "pid")
          const dynamicRoutes = transformRoutes(treeData)
          routes.value = constantRoutes.concat(dynamicRoutes)
          resolve(dynamicRoutes)
        })
        .catch((error) => {
          reject(error)
        })
    })
  }

  /**
   * 混合模式菜单下根据顶部菜单路径设置左侧菜单
   *
   * @param topMenuPath - 顶部菜单路径
   */
  const setMixLeftMenus = (topMenuPath: string) => {
    const matchedItem = routes.value.find((item) => item.path === topMenuPath)
    if (matchedItem && matchedItem.children) {
      mixLeftMenus.value = matchedItem.children
    }
  }

  return {
    routes,
    generateRoutes,
    mixLeftMenus,
    setMixLeftMenus,
  }
})

/**
 * 转换路由数据为组件
 */
const transformRoutes = (routes: RouteVO[]) => {
  const asyncRoutes: RouteRecordRaw[] = []
  routes.forEach((route) => {
    const tmpRoute = { ...route } as RouteRecordRaw
    // 顶级目录，替换为 Layout 组件
    if (tmpRoute.component?.toString() == "Layout") {
      tmpRoute.component = Layout
    } else {
      // 其他菜单，根据组件路径动态加载组件
      const component = modules[`../../views/${tmpRoute.component}.vue`]
      if (component) {
        tmpRoute.component = component
      } else {
        tmpRoute.component = modules[`../../views/error-page/404.vue`]
      }
    }

    if (tmpRoute.children && tmpRoute.children.length > 0) {
      tmpRoute.children = transformRoutes(route.children)
    }

    asyncRoutes.push(tmpRoute)
  })

  return asyncRoutes
}

/**
 * 用于在组件外部（如在Pinia Store 中）使用 Pinia 提供的 store 实例。
 * 官方文档解释了如何在组件外部使用 Pinia Store：
 * https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
 */
export function usePermissionStoreHook() {
  return usePermissionStore(store)
}
